#ifndef __LIST_CPP__
#define __LIST_CPP__
#include "../include/all.h"


// template <typename T> extern FILE* List<T>::file;

template <typename T>
List<T>::List() {
    head = new Node<T>;
    head->next = nullptr;
    tail = head;
}
template <typename T>
List<T>::~List() {
    clear();
    delete head;
}

template <typename T>
void List<T>::create() {
    counter = 0;
    file = fopen(T::path, "r");
    if (file) {
        readFile();
        fclose(file);
    }
}
template <typename T>
void List<T>::save() {
    file = fopen(T::path, "w");
    writeFile();
}

template <typename T>
void List<T>::readFile() {
    while (file) {
        auto pnew = new Node<T>;
        if (fread(&pnew->data, sizeof(T), 1, file) == 0) {
            delete pnew;
            break;
        }
        tail = tail->cat(pnew);
        ++counter;
    }
}
template <typename T>
void List<T>::writeFile() {
    traverse(Node<T>::serialize, Node<T>::nextNode);
}

template <typename T>
void List<T>::print() {
    traverse(Node<T>::print, Node<T>::nextNode);
    // system("pause");
    std::wcout << std::endl;
}
template <typename T>
void List<T>::clear() {
    traverse(Node<T>::erase, Node<T>::nowNode);
    tail = head;
    counter = 0;
}

template <typename T>
void List<T>::traverse(
    void     (*callback)(Node<T>* that),
    Node<T>* (*moveTo)(Node<T>* that)) {

    Node<T>* that = head;
    while (that->next) {
        callback(that);
        that = moveTo(that);
    }
}

template <typename T>
std::vector<Node<T>*>* List<T>::search(std::wstring& str) {
    std::vector<std::wstring> strs;
    std::vector<int> code;
    parse(str, strs, code);

    auto fndVec = new std::vector<Node<T>*>;
    Node<T>* that = head;
    while (that->next) {
        if (Node<T>::found(that, strs, code)) {
            fndVec->push_back(that);
        }
        that = Node<T>::nextNode(that);
    }
    return fndVec;
}

template class List<Student>;
template class List<Course>;


#endif /* __LIST_CPP__ */
